package com.uh.calculation.util;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.uh.calculation.batchJdbc.SqlThread;
import com.uh.calculation.bean.*;
import com.uh.microservice.core.util.ThreadPool;
import com.uh.summary.enums.RuleEnum;
import com.uh.summary.mapper.WarnEnterpriseRecordMapper;
import com.uh.summary.serviceImpl.BatchServerThread;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.EnumUtils;
import org.joda.time.DateTime;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class FormulaBatchUtil {

    private   Calculator cal ;

    private WarnEnterpriseRecordMapper warnEnterpriseRecordMapper;


    public FormulaBatchUtil(){

    }


    public FormulaBatchUtil(List<TbFeild> tbFeilds, List<FormulaBean> formulaBeans , WarnJiSuanBean warnJiSuanBean, SqlWriteBean sqlWriteBean){
        this.warnEnterpriseRecordMapper=warnJiSuanBean.getWarnEnterpriseRecordMapper();
             //计算公式数据替换

        //抛入公式算子获取计算结果
        String res = num(tbFeilds,formulaBeans);

        //有计算结果，写入预警
        if(!StringUtils.isEmpty(res)){
            List<WarnEnterpriseRecord> warnEnterpriseRecords = new ArrayList<>();
            WarnEnterpriseRecord warnEnterpriseRecord = new WarnEnterpriseRecord();
            JSONArray jsonArray201 = sqlWriteBean.getJsonArray201();
            //List<Map<String, Object>> F201_1ls  = warnJiSuanBean.getF201_1ls();
            if(jsonArray201!=null && jsonArray201.size()>0){
                JSONObject object = jsonArray201.getJSONObject(0);
                String region_area= object.get("region_area").toString();

                String province = getSubstring(region_area, 0, 2)+"0000";
                String city=  getSubstring(region_area, 0, 4)+"00";
                String area=  getSubstring(region_area, 0, 6);

                String  company_code= object.get("company_code").toString();
                String  company_name= object.get("company_name").toString();
                warnEnterpriseRecord.setProvince(province);
                warnEnterpriseRecord.setCity(city);
                warnEnterpriseRecord.setArea(area);
                warnEnterpriseRecord.setRegionArea(region_area);
                warnEnterpriseRecord.setCompanyCode(company_code);
                warnEnterpriseRecord.setCompanyName(company_name);
            }
            //System.out.println(warnEnterpriseRecord.getCompanyCode()+":"+sqlWriteBean.getDimension()+" : "+sqlWriteBean.getTimeCode()+"  : "+res);
            warnEnterpriseRecord.setWarnFactor(res);
            warnEnterpriseRecord.setCreateTime(new Date());
            warnEnterpriseRecord.setDimension(sqlWriteBean.getDimension());//预警类型
            warnEnterpriseRecord.setYearIsMonth(sqlWriteBean.getTimeCode());//预警时间warningIndex = "90.0"
            warnEnterpriseRecord.setWarnType(sqlWriteBean.getWarnType());
            warnEnterpriseRecord.setId(generateSnowFlake());
            warnEnterpriseRecord.setWarnCode(generateWarnCode(warnEnterpriseRecord.getDimension(), warnJiSuanBean.getStart(), String.valueOf(new DateTime(warnEnterpriseRecord.getCreateTime()).getYear())));
            warnJiSuanBean.setStart(warnJiSuanBean.getStart()+1);
            warnEnterpriseRecord.setMajorClassify(warnJiSuanBean.getSubjectCode());
            warnEnterpriseRecord.setWarnFactor(String.format("%.1f", Double.parseDouble(warnEnterpriseRecord.getWarnFactor())));
            if (sqlWriteBean.getWarnType() != null) {
                warnEnterpriseRecord.setWarningIndex(String.format("%.1f", generateWarnIndex(sqlWriteBean.getWarnType(), warnEnterpriseRecord.getWarnFactor())));
            } else {
                warnEnterpriseRecord.setWarningIndex("0.0");
            }


            String  sql =" insert into warn_enterprise_record (id, province, city, area, region_area, warn_code, credit," +
                    "        company_name,company_code,project_name," +
                    "        project_code,dimension,dimension_type,major_classify,warning_factor,year_is_month, is_del," +
                    "        warning_index)" +
                    "        values" +
                    "        " +
                    "            ('%s', '%s', '%s', '%s', '%s', '%s'," +
                    "            '%s'," +
                    "            '%s', '%s', '%s', '%s'," +
                    "            '%s', '%s', '%s', '%s', '%s'," +
                    "            '%s', '%s')";


            sql =String.format(sql,warnEnterpriseRecord.getId(),warnEnterpriseRecord.getProvince(),warnEnterpriseRecord.getCity(),warnEnterpriseRecord.getArea(),warnEnterpriseRecord.getRegionArea(),
                    warnEnterpriseRecord.getWarnCode(),warnEnterpriseRecord.getCredit(),warnEnterpriseRecord.getCompanyName(),warnEnterpriseRecord.getCompanyCode(),warnEnterpriseRecord.getProjectName(),
                    warnEnterpriseRecord.getProjectCode(),warnEnterpriseRecord.getDimension(),warnEnterpriseRecord.getWarnType(),warnEnterpriseRecord.getMajorClassify(),
                    warnEnterpriseRecord.getWarnFactor(),warnEnterpriseRecord.getYearIsMonth(),warnEnterpriseRecord.getIsDel(),warnEnterpriseRecord.getWarningIndex());

            ThreadPool.getInstance().getPool().submit(new SqlThread(sql,warnJiSuanBean.getJdbcDao()));
        }
    }


    private String generateSnowFlake() {
        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        return snowflake.nextIdStr();
    }


    private Double generateWarnIndex(String key, String factor) {
        Double weight = EnumUtils.getEnum(RuleEnum.class, key.toUpperCase()).getWeight();


        return Double.parseDouble(factor) * weight;
    }
    private String generateWarnCode(String dimension, Integer start, String year) {
        NumberFormat format = NumberFormat.getInstance();
        format.setMinimumIntegerDigits(8);
        format.setGroupingUsed(false);
        return dimension + year + format.format(start);
    }

    private String getSubstring(String string, Integer start, Integer end) {

        return  string.substring(start, end);
    }








    public   String  num (List<TbFeild> tbFeilds,List<FormulaBean> formulaBeans){
        SortList.sort(tbFeilds, "originalName", false);
        for(FormulaBean f:formulaBeans){
            String formula = f.getFormula();

            for(TbFeild t:tbFeilds) {
                formula =formula.replace(t.getOriginalName(),t.getData());
            }
            f.setNewFormula(formula);
        }
        try {
            cal = new Calculator();
            Integer num = 0;
            for (FormulaBean f : formulaBeans) {
                String formula = f.getNewFormula();
                String fs[] = formula.split("\\|");
                String condition = fs[0];
                String  str[] = condition.split("&");//支持与的条件
                if(getTrue(str)){
                    return cal.calculate(fs[1]);
                }
            }
        }catch (Exception e){
            return  null;
        }
        return  null;
    }



    public  Boolean getTrue(String [] condition){
        for(String str :condition){
            Boolean b = false;
            if (str.contains("<=")&&getResult(str, "<=")) {
                b = true;
            }
            if (str.contains(">=")&& getResult(str, ">=")) {
                b = true;
            }
            if (!str.contains("<=")&& getResult(str, "<")) {
                b = true;
            }
            if (!str.contains(">=")&& getResult(str, ">")) {
                b = true;
            }
            if (!str.contains("<=")&&!str.contains(">=")&& getResult(str, "=")) {
                b = true;
            }
            if(!b){
                return b;
            }
        }
        return  true;
    }






    public   Boolean  getResult (String condition,String symbol){
        try {
            if (condition.contains(symbol)) {
                String cs[] = condition.split(symbol);
                String zhi = cs[1];
                String str = cal.calculate(cs[0]);
                BigDecimal data1 = new BigDecimal(zhi);
                BigDecimal data2 = new BigDecimal(str);
                switch (symbol) {
                    case "<=":
                        if(data2.compareTo(data1) == -1 || data2.compareTo(data1) == 0){
                            return true;
                        }else{
                            return  false;
                        }
                    case ">=":
                        if(data2.compareTo(data1) == 1 || data2.compareTo(data1) == 0){
                            return true;
                        }else{
                            return  false;
                        }
                    case "<":
                        return data2.compareTo(data1) == -1;
                    case ">":
                        return data2.compareTo(data1) == 1;
                    case "=":
                        return data2.compareTo(data1) == 0;

                    default:
                }
            }
        }catch (Exception e){
            return  false;
        }
        return  false;
    }






    public static void main(String[] args) {
        String  s="3300000000000222";
        System.out.println(s.substring(0, 2));
        System.out.println(s.substring(0, 4));


    }

}